package benchmark;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Summerday
 */

@BenchmarkMode(Mode.Throughput) //测试类型 吞吐量
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) //预热2轮,每次1秒
@Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS) //测试5轮,每次3s
@Fork(1)  //fork 1个线程
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread) //每个测试线程1个实例
public class HashMapBenchmark {
    static Map<String, String> map = new HashMap<String,String>() {
        {
            put("author", "天乔巴夏");
            put("title", "HashMap的各种遍历方式");
            put("url", "www.hyhwky.com");
        }
    };

    public static void main(String[] args) throws RunnerException {
        System.out.println(System.getProperties());
        Options opt = new OptionsBuilder()
                .include(HashMapBenchmark.class.getSimpleName())
                .output(System.getProperty("user.dir") + "\\HashMapBenchmark.log")
                .build();
        new Runner(opt).run();
    }

    @Benchmark
    public void testEntrySet() {
        Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        }
    }

    @Benchmark
    public void testKeySet() {
        Iterator<String> iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            System.out.println(key + " --> " + map.get(key));
        }
    }

    @Benchmark
    public void testForEachEntrySet() {
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        }
    }

    @Benchmark
    public void testForEachKeySet() {
        for (String key : map.keySet()) {
            System.out.println(key + " --> " + map.get(key));
        }
    }

    @Benchmark
    public void testLambda() {
        map.forEach((key, value) -> {
            System.out.println(key + " --> " + value);
        });
    }

    @Benchmark
    public void testStream(){
        map.entrySet().stream().forEach(entry ->{
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        });
    }

    @Benchmark
    public void testParallelStream(){
        map.entrySet().parallelStream().forEach(entry ->{
            System.out.println(entry.getKey() + " --> " + entry.getValue());
        });
    }
}
